package com.lifeverse.service;

import com.lifeverse.entity.BehaviorPattern;
import com.lifeverse.entity.LifeEntityRelationship;
import com.lifeverse.entity.enums.PatternStatus;
import com.lifeverse.entity.enums.PatternType;
import com.lifeverse.repository.BehaviorPatternRepository;
import com.lifeverse.repository.LifeEntityRelationshipRepository;
import com.lifeverse.util.JsonUtils;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.math3.stat.correlation.PearsonsCorrelation;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 网络交互模式识别服务
 * 分析生命体之间的交互模式和网络行为
 */
@Service
@RequiredArgsConstructor
@Slf4j
public class NetworkPatternRecognitionService {

    private final BehaviorPatternRepository behaviorPatternRepository;
    private final LifeEntityRelationshipRepository relationshipRepository;
    private final JsonUtils jsonUtils;

    /**
     * 识别网络交互模式
     */
    @Transactional
    public List<BehaviorPattern> recognizeNetworkInteractionPatterns() {
        log.info("开始识别网络交互模式");
        
        List<BehaviorPattern> networkPatterns = new ArrayList<>();
        
        try {
            // 1. 识别集群模式
            networkPatterns.addAll(recognizeClusteringPatterns());
            
            // 2. 识别传播模式
            networkPatterns.addAll(recognizePropagationPatterns());
            
            // 3. 识别协作模式
            networkPatterns.addAll(recognizeCollaborationPatterns());
            
            // 4. 识别影响力模式
            networkPatterns.addAll(recognizeInfluencePatterns());
            
            // 5. 识别同步模式
            networkPatterns.addAll(recognizeSynchronizationPatterns());
            
            // 保存识别到的模式
            if (!networkPatterns.isEmpty()) {
                networkPatterns = behaviorPatternRepository.saveAll(networkPatterns);
                log.info("识别到 {} 个网络交互模式", networkPatterns.size());
            }
            
        } catch (Exception e) {
            log.error("识别网络交互模式时发生错误", e);
        }
        
        return networkPatterns;
    }

    /**
     * 识别集群模式
     * 检测生命体形成紧密连接群组的模式
     */
    private List<BehaviorPattern> recognizeClusteringPatterns() {
        List<BehaviorPattern> patterns = new ArrayList<>();
        
        try {
            // 获取所有关系
            List<LifeEntityRelationship> relationships = relationshipRepository.findAll();
            
            // 构建邻接图
            Map<Long, Set<Long>> adjacencyMap = buildAdjacencyMap(relationships);
            
            // 检测密集连接的集群
            List<Set<Long>> clusters = detectClusters(adjacencyMap);
            
            for (Set<Long> cluster : clusters) {
                if (cluster.size() >= 3) { // 至少3个节点才算集群
                    double clusterDensity = calculateClusterDensity(cluster, adjacencyMap);
                    
                    if (clusterDensity > 0.6) { // 密度阈值
                        BehaviorPattern pattern = createNetworkPattern(
                                PatternType.INTERACTION,
                                "集群交互模式",
                                String.format("检测到 %d 个生命体形成的密集集群，密度: %.2f", cluster.size(), clusterDensity),
                                createClusterFeatures(cluster, clusterDensity),
                                clusterDensity
                        );
                        patterns.add(pattern);
                    }
                }
            }
            
        } catch (Exception e) {
            log.error("识别集群模式时发生错误", e);
        }
        
        return patterns;
    }

    /**
     * 识别传播模式
     * 检测信息或行为在网络中的传播模式
     */
    private List<BehaviorPattern> recognizePropagationPatterns() {
        List<BehaviorPattern> patterns = new ArrayList<>();
        
        try {
            // 分析最近的行为模式传播
            LocalDateTime since = LocalDateTime.now().minus(7, ChronoUnit.DAYS);
            List<BehaviorPattern> recentPatterns = behaviorPatternRepository.findActivePatternsSince(since);
            
            // 按模式类型和时间分组
            Map<String, List<BehaviorPattern>> patternsByType = recentPatterns.stream()
                    .collect(Collectors.groupingBy(p -> p.getPatternType().name()));
            
            for (Map.Entry<String, List<BehaviorPattern>> entry : patternsByType.entrySet()) {
                String patternType = entry.getKey();
                List<BehaviorPattern> typePatterns = entry.getValue();
                
                // 分析传播特征
                PropagationAnalysis analysis = analyzePropagation(typePatterns);
                
                if (analysis.isPropagationDetected()) {
                    BehaviorPattern pattern = createNetworkPattern(
                            PatternType.COMMUNICATION,
                            "传播模式",
                            String.format("检测到 %s 类型模式的传播，传播速度: %.2f，覆盖范围: %d", 
                                    patternType, analysis.getSpeed(), analysis.getCoverage()),
                            createPropagationFeatures(analysis),
                            analysis.getConfidence()
                    );
                    patterns.add(pattern);
                }
            }
            
        } catch (Exception e) {
            log.error("识别传播模式时发生错误", e);
        }
        
        return patterns;
    }

    /**
     * 识别协作模式
     * 检测生命体之间的协作行为模式
     */
    private List<BehaviorPattern> recognizeCollaborationPatterns() {
        List<BehaviorPattern> patterns = new ArrayList<>();
        
        try {
            // 获取协作类型的关系
            List<LifeEntityRelationship> collaborations = relationshipRepository
                    .findByRelationshipType("COLLABORATION");
            
            if (collaborations.isEmpty()) {
                return patterns;
            }
            
            // 分析协作网络
            CollaborationAnalysis analysis = analyzeCollaborationNetwork(collaborations);
            
            if (analysis.hasSignificantPatterns()) {
                BehaviorPattern pattern = createNetworkPattern(
                        PatternType.COLLABORATION,
                        "协作网络模式",
                        String.format("检测到协作网络模式，参与者: %d，协作强度: %.2f", 
                                analysis.getParticipantCount(), analysis.getIntensity()),
                        createCollaborationFeatures(analysis),
                        analysis.getConfidence()
                );
                patterns.add(pattern);
            }
            
        } catch (Exception e) {
            log.error("识别协作模式时发生错误", e);
        }
        
        return patterns;
    }

    /**
     * 识别影响力模式
     * 检测网络中的影响力传播和层级结构
     */
    private List<BehaviorPattern> recognizeInfluencePatterns() {
        List<BehaviorPattern> patterns = new ArrayList<>();
        
        try {
            // 获取所有关系
            List<LifeEntityRelationship> relationships = relationshipRepository.findAll();
            
            // 计算影响力指标
            Map<Long, Double> influenceScores = calculateInfluenceScores(relationships);
            
            // 识别影响力中心
            List<Long> influencers = identifyInfluencers(influenceScores);
            
            if (!influencers.isEmpty()) {
                // 分析影响力网络结构
                InfluenceAnalysis analysis = analyzeInfluenceNetwork(influencers, relationships);
                
                BehaviorPattern pattern = createNetworkPattern(
                        PatternType.INTERACTION,
                        "影响力模式",
                        String.format("检测到 %d 个影响力中心，网络层级深度: %d", 
                                influencers.size(), analysis.getHierarchyDepth()),
                        createInfluenceFeatures(analysis),
                        analysis.getConfidence()
                );
                patterns.add(pattern);
            }
            
        } catch (Exception e) {
            log.error("识别影响力模式时发生错误", e);
        }
        
        return patterns;
    }

    /**
     * 识别同步模式
     * 检测生命体行为的同步性
     */
    private List<BehaviorPattern> recognizeSynchronizationPatterns() {
        List<BehaviorPattern> patterns = new ArrayList<>();
        
        try {
            // 获取最近的行为模式
            LocalDateTime since = LocalDateTime.now().minus(24, ChronoUnit.HOURS);
            List<BehaviorPattern> recentPatterns = behaviorPatternRepository.findActivePatternsSince(since);
            
            // 按生命体分组
            Map<Long, List<BehaviorPattern>> patternsByEntity = recentPatterns.stream()
                    .collect(Collectors.groupingBy(BehaviorPattern::getLifeEntityId));
            
            // 分析同步性
            SynchronizationAnalysis analysis = analyzeSynchronization(patternsByEntity);
            
            if (analysis.hasSynchronization()) {
                BehaviorPattern pattern = createNetworkPattern(
                        PatternType.BEHAVIOR,
                        "同步行为模式",
                        String.format("检测到 %d 个生命体的同步行为，同步度: %.2f", 
                                analysis.getSynchronizedEntities(), analysis.getSynchronizationLevel()),
                        createSynchronizationFeatures(analysis),
                        analysis.getConfidence()
                );
                patterns.add(pattern);
            }
            
        } catch (Exception e) {
            log.error("识别同步模式时发生错误", e);
        }
        
        return patterns;
    }

    /**
     * 构建邻接图
     */
    private Map<Long, Set<Long>> buildAdjacencyMap(List<LifeEntityRelationship> relationships) {
        Map<Long, Set<Long>> adjacencyMap = new HashMap<>();
        
        for (LifeEntityRelationship rel : relationships) {
            adjacencyMap.computeIfAbsent(rel.getSourceEntityId(), k -> new HashSet<>())
                    .add(rel.getTargetEntityId());
            adjacencyMap.computeIfAbsent(rel.getTargetEntityId(), k -> new HashSet<>())
                    .add(rel.getSourceEntityId());
        }
        
        return adjacencyMap;
    }

    /**
     * 检测集群
     */
    private List<Set<Long>> detectClusters(Map<Long, Set<Long>> adjacencyMap) {
        List<Set<Long>> clusters = new ArrayList<>();
        Set<Long> visited = new HashSet<>();
        
        for (Long nodeId : adjacencyMap.keySet()) {
            if (!visited.contains(nodeId)) {
                Set<Long> cluster = new HashSet<>();
                dfsCluster(nodeId, adjacencyMap, visited, cluster);
                
                if (cluster.size() > 1) {
                    clusters.add(cluster);
                }
            }
        }
        
        return clusters;
    }

    /**
     * 深度优先搜索集群
     */
    private void dfsCluster(Long nodeId, Map<Long, Set<Long>> adjacencyMap, 
                           Set<Long> visited, Set<Long> cluster) {
        visited.add(nodeId);
        cluster.add(nodeId);
        
        Set<Long> neighbors = adjacencyMap.get(nodeId);
        if (neighbors != null) {
            for (Long neighbor : neighbors) {
                if (!visited.contains(neighbor)) {
                    dfsCluster(neighbor, adjacencyMap, visited, cluster);
                }
            }
        }
    }

    /**
     * 计算集群密度
     */
    private double calculateClusterDensity(Set<Long> cluster, Map<Long, Set<Long>> adjacencyMap) {
        int nodeCount = cluster.size();
        int edgeCount = 0;
        
        for (Long nodeId : cluster) {
            Set<Long> neighbors = adjacencyMap.get(nodeId);
            if (neighbors != null) {
                for (Long neighbor : neighbors) {
                    if (cluster.contains(neighbor)) {
                        edgeCount++;
                    }
                }
            }
        }
        
        edgeCount /= 2; // 无向图，每条边被计算了两次
        int maxPossibleEdges = nodeCount * (nodeCount - 1) / 2;
        
        return maxPossibleEdges == 0 ? 0.0 : (double) edgeCount / maxPossibleEdges;
    }

    /**
     * 分析传播
     */
    private PropagationAnalysis analyzePropagation(List<BehaviorPattern> patterns) {
        PropagationAnalysis analysis = new PropagationAnalysis();
        
        if (patterns.size() < 3) {
            return analysis;
        }
        
        // 按时间排序
        patterns.sort(Comparator.comparing(BehaviorPattern::getFirstDetectedAt));
        
        // 计算传播速度
        LocalDateTime firstTime = patterns.get(0).getFirstDetectedAt();
        LocalDateTime lastTime = patterns.get(patterns.size() - 1).getFirstDetectedAt();
        long timeDiff = ChronoUnit.HOURS.between(firstTime, lastTime);
        
        if (timeDiff > 0) {
            analysis.setSpeed((double) patterns.size() / timeDiff);
            analysis.setCoverage(patterns.stream()
                    .map(BehaviorPattern::getLifeEntityId)
                    .collect(Collectors.toSet()).size());
            analysis.setPropagationDetected(true);
            analysis.setConfidence(Math.min(analysis.getSpeed() / 10.0, 1.0));
        }
        
        return analysis;
    }

    /**
     * 分析协作网络
     */
    private CollaborationAnalysis analyzeCollaborationNetwork(List<LifeEntityRelationship> collaborations) {
        CollaborationAnalysis analysis = new CollaborationAnalysis();
        
        Set<Long> participants = new HashSet<>();
        double totalStrength = 0.0;
        
        for (LifeEntityRelationship collab : collaborations) {
            participants.add(collab.getSourceEntityId());
            participants.add(collab.getTargetEntityId());
            totalStrength += collab.getStrength();
        }
        
        analysis.setParticipantCount(participants.size());
        analysis.setIntensity(collaborations.isEmpty() ? 0.0 : totalStrength / collaborations.size());
        analysis.setSignificantPatterns(participants.size() >= 3 && analysis.getIntensity() > 0.5);
        analysis.setConfidence(Math.min(analysis.getIntensity(), 1.0));
        
        return analysis;
    }

    /**
     * 计算影响力分数
     */
    private Map<Long, Double> calculateInfluenceScores(List<LifeEntityRelationship> relationships) {
        Map<Long, Double> scores = new HashMap<>();
        Map<Long, Integer> inDegree = new HashMap<>();
        Map<Long, Integer> outDegree = new HashMap<>();
        
        // 计算入度和出度
        for (LifeEntityRelationship rel : relationships) {
            inDegree.merge(rel.getTargetEntityId(), 1, Integer::sum);
            outDegree.merge(rel.getSourceEntityId(), 1, Integer::sum);
        }
        
        // 计算影响力分数（结合入度、出度和关系强度）
        Set<Long> allEntities = new HashSet<>();
        allEntities.addAll(inDegree.keySet());
        allEntities.addAll(outDegree.keySet());
        
        for (Long entityId : allEntities) {
            int in = inDegree.getOrDefault(entityId, 0);
            int out = outDegree.getOrDefault(entityId, 0);
            
            // 简化的影响力计算：出度权重更高
            double influence = out * 2.0 + in * 1.0;
            scores.put(entityId, influence);
        }
        
        return scores;
    }

    /**
     * 识别影响者
     */
    private List<Long> identifyInfluencers(Map<Long, Double> influenceScores) {
        double threshold = influenceScores.values().stream()
                .mapToDouble(Double::doubleValue)
                .average()
                .orElse(0.0) * 1.5; // 高于平均值50%
        
        return influenceScores.entrySet().stream()
                .filter(entry -> entry.getValue() > threshold)
                .map(Map.Entry::getKey)
                .collect(Collectors.toList());
    }

    /**
     * 分析影响力网络
     */
    private InfluenceAnalysis analyzeInfluenceNetwork(List<Long> influencers, 
                                                     List<LifeEntityRelationship> relationships) {
        InfluenceAnalysis analysis = new InfluenceAnalysis();
        
        // 简化的层级深度计算
        analysis.setHierarchyDepth(Math.min(influencers.size() / 2 + 1, 5));
        analysis.setConfidence(Math.min((double) influencers.size() / 10.0, 1.0));
        
        return analysis;
    }

    /**
     * 分析同步性
     */
    private SynchronizationAnalysis analyzeSynchronization(Map<Long, List<BehaviorPattern>> patternsByEntity) {
        SynchronizationAnalysis analysis = new SynchronizationAnalysis();
        
        if (patternsByEntity.size() < 2) {
            return analysis;
        }
        
        // 计算时间同步性
        List<List<LocalDateTime>> timeSeries = patternsByEntity.values().stream()
                .map(patterns -> patterns.stream()
                        .map(BehaviorPattern::getLastDetectedAt)
                        .sorted()
                        .collect(Collectors.toList()))
                .collect(Collectors.toList());
        
        double synchronization = calculateTimeSynchronization(timeSeries);
        
        if (synchronization > 0.6) {
            analysis.setSynchronizedEntities(patternsByEntity.size());
            analysis.setSynchronizationLevel(synchronization);
            analysis.setSynchronization(true);
            analysis.setConfidence(synchronization);
        }
        
        return analysis;
    }

    /**
     * 计算时间同步性
     */
    private double calculateTimeSynchronization(List<List<LocalDateTime>> timeSeries) {
        if (timeSeries.size() < 2) return 0.0;
        
        // 简化的同步性计算：比较时间序列的相关性
        // 这里使用时间间隔的相关性作为同步性指标
        
        List<Double> intervals1 = calculateIntervals(timeSeries.get(0));
        List<Double> intervals2 = calculateIntervals(timeSeries.get(1));
        
        if (intervals1.size() < 2 || intervals2.size() < 2) return 0.0;
        
        // 使用皮尔逊相关系数
        int minSize = Math.min(intervals1.size(), intervals2.size());
        double[] array1 = intervals1.subList(0, minSize).stream().mapToDouble(Double::doubleValue).toArray();
        double[] array2 = intervals2.subList(0, minSize).stream().mapToDouble(Double::doubleValue).toArray();
        
        try {
            PearsonsCorrelation correlation = new PearsonsCorrelation();
            return Math.abs(correlation.correlation(array1, array2));
        } catch (Exception e) {
            return 0.0;
        }
    }

    /**
     * 计算时间间隔
     */
    private List<Double> calculateIntervals(List<LocalDateTime> times) {
        List<Double> intervals = new ArrayList<>();
        
        for (int i = 1; i < times.size(); i++) {
            long interval = ChronoUnit.MINUTES.between(times.get(i-1), times.get(i));
            intervals.add((double) interval);
        }
        
        return intervals;
    }

    /**
     * 创建网络模式
     */
    private BehaviorPattern createNetworkPattern(PatternType type, String name, String description,
                                               Map<String, Object> features, double confidence) {
        BehaviorPattern pattern = new BehaviorPattern();
        pattern.setLifeEntityId(0L); // 网络级别的模式
        pattern.setPatternType(type);
        pattern.setPatternName(name);
        pattern.setDescription(description);
        pattern.setFeatureVector(jsonUtils.toJson(features));
        pattern.setConfidenceScore(confidence);
        pattern.setFrequency(1);
        pattern.setStatus(PatternStatus.ACTIVE);
        pattern.setFirstDetectedAt(LocalDateTime.now());
        pattern.setLastDetectedAt(LocalDateTime.now());
        pattern.setAnomalyScore(0.0);
        
        return pattern;
    }

    /**
     * 创建集群特征
     */
    private Map<String, Object> createClusterFeatures(Set<Long> cluster, double density) {
        Map<String, Object> features = new HashMap<>();
        features.put("cluster_size", cluster.size());
        features.put("cluster_density", density);
        features.put("cluster_members", cluster);
        return features;
    }

    /**
     * 创建传播特征
     */
    private Map<String, Object> createPropagationFeatures(PropagationAnalysis analysis) {
        Map<String, Object> features = new HashMap<>();
        features.put("propagation_speed", analysis.getSpeed());
        features.put("coverage", analysis.getCoverage());
        return features;
    }

    /**
     * 创建协作特征
     */
    private Map<String, Object> createCollaborationFeatures(CollaborationAnalysis analysis) {
        Map<String, Object> features = new HashMap<>();
        features.put("participant_count", analysis.getParticipantCount());
        features.put("collaboration_intensity", analysis.getIntensity());
        return features;
    }

    /**
     * 创建影响力特征
     */
    private Map<String, Object> createInfluenceFeatures(InfluenceAnalysis analysis) {
        Map<String, Object> features = new HashMap<>();
        features.put("hierarchy_depth", analysis.getHierarchyDepth());
        return features;
    }

    /**
     * 创建同步特征
     */
    private Map<String, Object> createSynchronizationFeatures(SynchronizationAnalysis analysis) {
        Map<String, Object> features = new HashMap<>();
        features.put("synchronized_entities", analysis.getSynchronizedEntities());
        features.put("synchronization_level", analysis.getSynchronizationLevel());
        return features;
    }

    // 内部分析类
    private static class PropagationAnalysis {
        private boolean propagationDetected = false;
        private double speed = 0.0;
        private int coverage = 0;
        private double confidence = 0.0;

        // getters and setters
        public boolean isPropagationDetected() { return propagationDetected; }
        public void setPropagationDetected(boolean propagationDetected) { this.propagationDetected = propagationDetected; }
        public double getSpeed() { return speed; }
        public void setSpeed(double speed) { this.speed = speed; }
        public int getCoverage() { return coverage; }
        public void setCoverage(int coverage) { this.coverage = coverage; }
        public double getConfidence() { return confidence; }
        public void setConfidence(double confidence) { this.confidence = confidence; }
    }

    private static class CollaborationAnalysis {
        private int participantCount = 0;
        private double intensity = 0.0;
        private boolean significantPatterns = false;
        private double confidence = 0.0;

        // getters and setters
        public int getParticipantCount() { return participantCount; }
        public void setParticipantCount(int participantCount) { this.participantCount = participantCount; }
        public double getIntensity() { return intensity; }
        public void setIntensity(double intensity) { this.intensity = intensity; }
        public boolean hasSignificantPatterns() { return significantPatterns; }
        public void setSignificantPatterns(boolean significantPatterns) { this.significantPatterns = significantPatterns; }
        public double getConfidence() { return confidence; }
        public void setConfidence(double confidence) { this.confidence = confidence; }
    }

    private static class InfluenceAnalysis {
        private int hierarchyDepth = 0;
        private double confidence = 0.0;

        // getters and setters
        public int getHierarchyDepth() { return hierarchyDepth; }
        public void setHierarchyDepth(int hierarchyDepth) { this.hierarchyDepth = hierarchyDepth; }
        public double getConfidence() { return confidence; }
        public void setConfidence(double confidence) { this.confidence = confidence; }
    }

    private static class SynchronizationAnalysis {
        private boolean synchronization = false;
        private int synchronizedEntities = 0;
        private double synchronizationLevel = 0.0;
        private double confidence = 0.0;

        // getters and setters
        public boolean hasSynchronization() { return synchronization; }
        public void setSynchronization(boolean synchronization) { this.synchronization = synchronization; }
        public int getSynchronizedEntities() { return synchronizedEntities; }
        public void setSynchronizedEntities(int synchronizedEntities) { this.synchronizedEntities = synchronizedEntities; }
        public double getSynchronizationLevel() { return synchronizationLevel; }
        public void setSynchronizationLevel(double synchronizationLevel) { this.synchronizationLevel = synchronizationLevel; }
        public double getConfidence() { return confidence; }
        public void setConfidence(double confidence) { this.confidence = confidence; }
    }
}